﻿using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace LightCAD.Core
{
    public class LcDocument
    {
        public static LcDocument Create(string filePath)
        {
            var doc = new LcDocument();
            doc.Initialize();
            doc.FilePath = filePath;
            return doc;
        }
        public static void SetCurrent(LcDocument document)
        {
            LcDocument.Current = document;
        }
        public static bool Save(LcDocument doc, string filePath)
        {
            var json = ToJson(doc);
            File.WriteAllText(filePath, json);
            return true;
        }
        public static string ToJson(LcDocument doc, bool indented = false)
        {
            

            var options = new JsonSerializerOptions
            { 
                 
                ReferenceHandler = ReferenceHandler.Preserve,
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
                WriteIndented = indented,
                //Converters = { new IEnumerableTConverter() }
            };
            return JsonSerializer.Serialize<LcDocument>(doc, options);
        }
        public static LcDocument Load(string filePath)
        {
            var json = File.ReadAllText(filePath);
            return FromJson(json);
        }
        public static LcDocument FromJson(string docJson)
        {
            var options = new JsonSerializerOptions
            {
                ReferenceHandler = ReferenceHandler.Preserve,
            };
            var doc = JsonSerializer.Deserialize<LcDocument>(docJson, options);
            doc.BuildStruct();
            return doc;
        }
        public const string Version = "1.0";
        [JsonIgnore]
        public static LcDocument Current { get; private set; }

        public LcDocument()
        {
            this.IdCreator = new IdCreator();
        }

        [JsonIgnore]
        public IdCreator IdCreator { get; private set; }

        [JsonIgnore]
        public string FilePath { get;  set; }

        public DocumentInfo Info { get; set; }

        public ProjectInfo ProjectInfo { get; set; }

        public ObjectPropertiesDefinitionMap ObjectPropertiesMap { get; internal set; }
        public PluginDefinitionMap PluginMap { get; internal set; }
        public ComponentDefinitionMap ComponentMap { get; internal set; }
        public Dictionary<string, ComponentInstanceCollection> ComponentInstances { get; set; }


        [JsonInclude]
        public UCSCollection UCSs { get; internal set; }

        [JsonInclude]
        public ElementStyleCollction Styles { get; internal set; }

        [JsonInclude]
        public TextStyleCollection TextStyles { get; internal set; }

        [JsonInclude]
        public BlockCollection Blocks { get; internal set; }

        [JsonInclude]
        public XrefCollection Xrefs { get; internal set; }

        [JsonInclude]
        public GroupCollection Groups { get; internal set; }

        [JsonInclude]
        public LayerCollection Layers { get; internal set; }

        [JsonInclude]
        public LineTypeCollection LineTypes { get; internal set; }

        [JsonInclude]
        public ViewportCollection Viewports { get; internal set; }

        [JsonInclude]
        public ViewCollection Views { get; internal set; }

        /// <summary>
        /// 是不是模型图纸
        /// </summary>
        public bool IsModelDrawing { get; set; }
        
        /// <summary>
        /// 模型图纸信息
        /// </summary>
        public ModelDrawing ModelDrawing { get; set; }
        
        /// <summary>
        /// 相关联的模型图纸信息
        /// </summary>
        public List<ModelDrawing> RelModelDrawings { get; set; }

        [JsonInclude]
        public BuildingCollection Buildings { get; internal set; }

        [JsonInclude]
        public DrawingFrameCollection DrawingFrames { get; internal set; }

        [JsonInclude]
        public SolidProfileCollection Profiles { get; internal set; }

        [JsonInclude]
        public ModelSpace ModelSpace { get; internal set; }

        [JsonInclude]
        public PaperSpace PaperSpace { get; internal set; }


        public Layer ActiveLayer { get; set; }
        public Viewport ActiveViewport { get; set; }
        public ActiveSpace ActiveSpace { get; set; }
        public UCS ActiveUCS { get; set; }

        public ResourceCollection Resources { get; set; }

        public T CreateObject<T>() where T : LcadObject
        {
            var obj= (T)Activator.CreateInstance(typeof(T));
            obj.Initilize(this);
            return obj;
        }
        /// <summary>
        /// 初始化文档对象，JSON序列化不需要调用
        /// </summary>
        public void Initialize()
        {
            this.ModelSpace = new ModelSpace(this);
            this.PaperSpace = new PaperSpace(this);
            //if (ObjectPropsDefMap == null)
            //{
            //    ObjectPropsDefMap = new ObjectPropertiesDefinitionMap();

            //    var sumProps = new ObjectPropertiesDefinition("LightCAD.SummaryInfo");
            //    var propGrp = sumProps.AddGroup("QdDocument", "启道协同-文档信息");
            //    propGrp.PropDefs.Add(new PropertyDefinition { Name = "Attr1", Display = "属性1" });
            //    ObjectPropsDefMap.Add(sumProps);

            //    var prjProps = new ObjectPropertiesDefinition("LightCAD.ProjectInfo");
            //    propGrp = prjProps.AddGroup("QdProject", "启道协同-项目信息");
            //    propGrp.PropDefs.Add(new PropertyDefinition { Name = "Attr2", Display = "属性2" });
            //    ObjectPropsDefMap.Add(prjProps);

            //}
        }

        private void BuildStruct()
        {
            this.ModelSpace.Document = this;
            if (this.ModelSpace.Elements.Count > 0)
            {
                foreach (var ele in this.ModelSpace.Elements)
                {
                    ele.Document = this;
                    IdCreator.RestObjectIdMax(ele.Id);
                }
            }
            this.PaperSpace.Document = this;
        }

        private ElementStyleManager _styleManager;
        [JsonIgnore]
        public ElementStyleManager StyleManager
        {
            get
            {
                if (_styleManager == null)
                {
                    _styleManager = new ElementStyleManager(this);
                }
                return _styleManager;
            }
        }

        #region evets
        //文档操作提供以下四个基本事件
        //对象本身发生变化
        public event EventHandler<ObjectChangedEventArgs> ObjectChangedBefore;
        public event EventHandler<ObjectChangedEventArgs> ObjectChangedAfter;
        //对象的属性发生变化
        public event EventHandler<PropertyChangedEventArgs> PropertyChangedBefore;
        public event EventHandler<PropertyChangedEventArgs> PropertyChangedAfter;

        public void OnPropertyChangedBefore(PropertyChangedEventArgs args)
        {
            PropertyChangedBefore?.Invoke(this, args);
        }
        public void OnPropertyChangedAfter(PropertyChangedEventArgs args)
        {
            PropertyChangedAfter?.Invoke(this, args);
        }
        public void OnObjectChangedBefore(ObjectChangedEventArgs args)
        {
            ObjectChangedBefore?.Invoke(this, args);
        }
        public void OnObjectChangedAfter(ObjectChangedEventArgs args)
        {
            ObjectChangedAfter?.Invoke(this, args);
        }

        #endregion

    }
}